#include "s3c2440_soc.h"
#include "uart.h"

typedef void(*irq_func)(int);
irq_func irq_array[32];

/*
 * 
 * SRCPND用来显示哪个中断产生了,需要清除对应的位
 * bit0-eint0
 * bit2-eint2
 * bit5-eint8_23
 */

/*
 * INTMSK用来屏蔽中断,1-masked
 * bit0-eint0
 * bit2-eint2
 * bit5-eint8_23
 */


/*
 * INTPND用来显示当前优先级最高的,正在发生的中断,需要清除对应位
 * bit0-eint0
 * bit2-eint2
 * bit5-eint8_23
 */

/* 初始化中断控制器 */
void interrupt_init(void)
{
    puts("interrupt _ init ");
    INTMSK &= ~((1<<0)|(1<<2)|(1<<5));
}



/*
 * 读EINTPEND分辨哪个EINT产生(eint4~23)
 * 清除中断时,写EINTPEND的响应位
 */

void key_eint_irq(int irq)
{
    unsigned int val = EINTPEND;
    unsigned int val1 = GPFDAT;
    unsigned int val2 = GPGDAT;

    if(irq == 0){//eint0 : s2 控制 D12
	if(val1 & (1<<0)){ //s2 -> gpf6
	    //松开
	    GPFDAT |= (1<<6);
	}else{
	    //按下
	    GPFDAT &= ~(1<<6);
	} 
    }else if(irq == 2){ //eint2 : s3控制D11
	if(val1 & (1<<2)){ //s3 -> gpf5
	    //松开
	    GPFDAT |= (1<<5);
	}else{
	    GPFDAT &= ~(1<<5);
	}

    }else if(irq == 5){ //eint8_23, eint11--s4控制D10 , eint19 --s5 控制所有LED
	if(val & (1<<11))
	{ // eint11

	    if (val2 & (1<<3)) /* s4 --> gpf4 */
	    {
		/* 松开 */
		GPFDAT |= (1<<4);
	    }
	    else
	    {
		/* 按下 */
		GPFDAT &= ~(1<<4);
	    }
	}
	else if (val & (1<<19)) /* eint19 */
	{
	    if (val2 & (1<<11))
	    {
		/* 松开 */
		/* 熄灭所有LED */
		GPFDAT |= ((1<<4) | (1<<5) | (1<<6));
	    }
		else
		{
		    /* 按下: 点亮所有LED */
		    GPFDAT &= ~((1<<4) | (1<<5) | (1<<6));
		}
	    }
    }
    EINTPEND = val;
}

void handle_irq_c(void)
{
    /* puts("handle irq c"); */
    // 分辨终端源
    int bit = INTOFFSET;

    //调用对应的处理函数
    /* if(bit ==0 || bit == 2 || bit == 5) */
    /* { */
	/* key_eint_irq(bit);//处理中断,清中断源EINTPEND */
    /* } */
    
    irq_array[bit](bit);

    // 清中断: 从源头开始
    SRCPND = (1<<bit);
    INTPND = (1<<bit);
}

void register_irq(int irq,irq_func fp)
{

    irq_array[irq] = fp;
    INTMSK &= ~(1<<irq);
}

/* 初始化按键,设置中断源 */
void key_eint_init(void)
{
    puts("key eint  _ init ");
    //配置GPIO s2,s3设置为中断引脚
    GPFCON &= ~((3<<0) | (3<<4));
    GPFCON |= ((2<<0) | (2<<4));

    //s4,s5配置为中断引脚
    GPGCON &= ~((3<<6) | (3<<22));
    GPGCON |= ((2<<6) | (2<<22));

    //设置中断出发方式:双边沿触发
    EXTINT0 |= (7<<0) | (7<<8); //s2,s3
    EXTINT1 |= (7<<12);         //s4
    EXTINT2 |= (7<<12);         //s5

    //设置EINTMASK使能eint11,19
    EINTMASK &= ~((1<<11) | (1<<19));

    register_irq(0,key_eint_irq);
    register_irq(2,key_eint_irq);
    register_irq(5,key_eint_irq);
}
